package com.bwie.house.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.bwie.house.vo.RentalSearchVo;
import com.bwie.house.vo.RentalVo;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.common.utils.PageUtils;
import com.bwie.common.utils.Query;

import com.bwie.house.dao.RentalDao;
import com.bwie.house.entity.RentalEntity;
import com.bwie.house.service.RentalService;


@Service("rentalService")
public class RentalServiceImpl extends ServiceImpl<RentalDao, RentalEntity> implements RentalService {
    @Autowired
    private RestHighLevelClient client;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<RentalEntity> page = this.page(
                new Query<RentalEntity>().getPage(params),
                new QueryWrapper<RentalEntity>()
        );

        return new PageUtils(page);
    }

    //出租房
    @Override
    public List<RentalVo> rentalVoEs() {
        return baseMapper.rentalVoEs();
    }

    //出租房es查询
    @Override
    public PageUtils rentalEsList(RentalSearchVo rentalSearchVo) throws IOException {

        ArrayList<RentalEntity> list = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest("rental");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //构建查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //模糊查询
        //1、出租房名称
        if (rentalSearchVo.getRentalName()!=null && !"".equals(rentalSearchVo.getRentalName())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("rentalName",rentalSearchVo.getRentalName()));
        }
        //2、出租房地址
        if (rentalSearchVo.getRentalAddress()!=null && !"".equals(rentalSearchVo.getRentalAddress())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("rentalAddress",rentalSearchVo.getRentalAddress()));
        }
        //租金区间查询
        if (rentalSearchVo.getRentalPrice1()!=null){
            boolQueryBuilder.must(QueryBuilders.rangeQuery("rentalPrice").gte(rentalSearchVo.getRentalPrice1()));
        }
        if (rentalSearchVo.getRentalPrice2()!=null){
            boolQueryBuilder.must(QueryBuilders.rangeQuery("rentalPrice").lte(rentalSearchVo.getRentalPrice2()));
        }
        //县精确查询
        if (rentalSearchVo.getXianId()!=null && rentalSearchVo.getXianId()!=0){
            boolQueryBuilder.must(QueryBuilders.termQuery("xianId",rentalSearchVo.getXianId()));
        }
        //类型精确县查询
        if (rentalSearchVo.getRentalStatus()!=null && rentalSearchVo.getRentalStatus()!=3){
            boolQueryBuilder.must(QueryBuilders.termQuery("rentalStatus",rentalSearchVo.getRentalStatus()));
        }
        searchSourceBuilder.query(boolQueryBuilder);


        if(rentalSearchVo.getStatus()!=null){
//            1-价格低到高
            if(rentalSearchVo.getStatus()==1){
                searchSourceBuilder.sort("rentalPrice", SortOrder.ASC);
//                2-价格高到低
            }else if(rentalSearchVo.getStatus()==2){
                searchSourceBuilder.sort("rentalPrice", SortOrder.DESC);
//                3-面积
            }else if(rentalSearchVo.getStatus()==3){
                searchSourceBuilder.sort("rentalArea", SortOrder.ASC);
//                4-面积  desc
            }else if(rentalSearchVo.getStatus()==4){
                searchSourceBuilder.sort("rentalArea", SortOrder.DESC);
            }else{
                //默认按照 id 升序
                searchSourceBuilder.sort("rentalId", SortOrder.ASC);
            }
        }

        searchRequest.source(searchSourceBuilder);

        //处理
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //执行
        SearchHits hits = searchResponse.getHits();
        TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
        long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
        TotalHits.Relation relation = totalHits.relation;
        float maxScore = hits.getMaxScore();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            // do something with the SearchHit
            String index = hit.getIndex();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            RentalEntity rentalEntity = JSONObject.parseObject(sourceAsString, new TypeReference<RentalEntity>() {
            });
            rentalEntity.setRentalId(Integer.valueOf(id));
            list.add(rentalEntity);
        }
        return  new PageUtils(list, (int) numHits,1,3);
    }

}